home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2001 December / pcwk12201b.iso / Wersje pelne i specjalne / Winamp 2.77 i 3.0beta / wasabi-sdk_beta1.exe / studio / common / scbkgwnd.cpp < prev    next >
C/C++ Source or Header  |  2001-10-08  |  19KB  |  741 lines

  1. /*
  2.  
  3.   Nullsoft WASABI Source File License
  4.  
  5.   Copyright 1999-2001 Nullsoft, Inc.
  6.  
  7.     This software is provided 'as-is', without any express or implied
  8.     warranty.  In no event will the authors be held liable for any damages
  9.     arising from the use of this software.
  10.  
  11.     Permission is granted to anyone to use this software for any purpose,
  12.     including commercial applications, and to alter it and redistribute it
  13.     freely, subject to the following restrictions:
  14.  
  15.     1. The origin of this software must not be misrepresented; you must not
  16.        claim that you wrote the original software. If you use this software
  17.        in a product, an acknowledgment in the product documentation would be
  18.        appreciated but is not required.
  19.     2. Altered source versions must be plainly marked as such, and must not be
  20.        misrepresented as being the original software.
  21.     3. This notice may not be removed or altered from any source distribution.
  22.  
  23.  
  24.   Brennan Underwood
  25.   brennan@nullsoft.com
  26.  
  27. */
  28.  
  29. #include <windows.h>
  30. #include <commctrl.h>
  31. #include "../common/scbkgwnd.h"
  32.  
  33. #define SCROLLBAR_SEP       4
  34. #define TIMER_SMOOTHSCROLLY 8873
  35. #define TIMER_SMOOTHSCROLLX 8874
  36. #define SMOOTH_STEPS        5
  37.  
  38. ScrlBkgWnd::ScrlBkgWnd() {
  39.   inDestroy = FALSE;
  40.     bmp = NULL;
  41.   bgColor = CLR_NONE;
  42.     hScroll = NULL;
  43.     vScroll = NULL;
  44.     hSep = NULL;
  45.     vSep = NULL;
  46.   scrollX = 0;
  47.   scrollY = 0;
  48.   dbbuffer=1;
  49.   needSetSliders=FALSE;
  50.   lineHeight = 16;
  51.   wantsep=0;
  52.   lastratio = 1.0;
  53.   MEMSET(&smsqr, 0, sizeof(RECT));
  54. }
  55.  
  56. ScrlBkgWnd::~ScrlBkgWnd() {
  57.   inDestroy = TRUE;
  58.     if (hScroll) delete hScroll;
  59.     hScroll = NULL;
  60.     if (vScroll) delete vScroll;
  61.     vScroll = NULL;
  62.     if (hSep) delete hSep;
  63.     hSep = NULL;
  64.     if (vSep) delete vSep;
  65.     vSep = NULL;
  66. }
  67.  
  68. ScrlBkgWnd::onInit() {
  69.  
  70.   SCRLBKGWND_PARENT::onInit();
  71.  
  72.     scrollY=0;
  73.     scrollX=0;
  74.  
  75.     hScroll = new ScrollBar();
  76.     hSep = new SepWnd();
  77.     hSep->setOrientation(SEP_HORIZONTAL);
  78.  
  79.   hScroll->setBitmaps("studio.scrollbar.horizontal.left", "studio.scrollbar.horizontal.left.pressed", "studio.scrollbar.horizontal.left.hilite",
  80.                       "studio.scrollbar.horizontal.right", "studio.scrollbar.horizontal.right.pressed", "studio.scrollbar.horizontal.right.hilite",
  81.                       "studio.scrollbar.horizontal.button", "studio.scrollbar.horizontal.button.pressed", "studio.scrollbar.horizontal.button.hilite");
  82.  
  83.     vScroll = new ScrollBar();
  84.     vSep = new SepWnd();
  85.     vSep->setOrientation(SEP_VERTICAL);
  86.  
  87.   vScroll->setBitmaps("studio.scrollbar.vertical.left", "studio.scrollbar.vertical.left.pressed", "studio.scrollbar.vertical.left.hilite",
  88.                       "studio.scrollbar.vertical.right", "studio.scrollbar.vertical.right.pressed", "studio.scrollbar.vertical.right.hilite",
  89.                       "studio.scrollbar.vertical.button", "studio.scrollbar.vertical.button.pressed", "studio.scrollbar.vertical.button.hilite");
  90.  
  91. //    hScroll->setVertical(FALSE);
  92.     vScroll->setVertical(TRUE);
  93.  
  94.     hScroll->setStartHidden(TRUE);  // prevent showing window at creation
  95.     vScroll->setStartHidden(TRUE);
  96.     hSep->setStartHidden(TRUE);
  97.     vSep->setStartHidden(TRUE);
  98.  
  99.     hScroll->setParent(this);
  100.     vScroll->setParent(this);
  101.     hSep->setParent(this);
  102.     vSep->setParent(this);
  103.  
  104.     hScroll->init(gethInstance(), gethWnd());
  105.     vScroll->init(gethInstance(), gethWnd());
  106.     hSep->init(gethInstance(), gethWnd());
  107.     vSep->init(gethInstance(), gethWnd());
  108.  
  109.     hScroll->setPosition(0);
  110.     vScroll->setPosition(0);
  111.  
  112.     setSlidersPosition();           // position sliders and show them if needed
  113.   return 1;
  114. }
  115.  
  116. void ScrlBkgWnd::setBgBitmap(char *b) {
  117.   bmp = b;
  118.   if (b)
  119.       setBgColor(CLR_NONE);
  120. }
  121.  
  122. void ScrlBkgWnd::setBgColor(COLORREF rgb) {
  123.   bgColor = rgb;
  124. }
  125.  
  126. SkinBitmap *ScrlBkgWnd::getBgBitmap(void) {
  127.   return bmp;
  128. }
  129.  
  130. COLORREF ScrlBkgWnd::getBgColor(void) {
  131.   return bgColor;
  132. }
  133.  
  134. // Scroll to a specified Y-pixels
  135. void ScrlBkgWnd::scrollToY(int y, int signal) {
  136.   WndCanvas *canvas=NULL;
  137.   RECT r;
  138.   int offset;
  139.  
  140.   if (ABS(getRenderRatio() - 1.0) > 0.01) {
  141.       scrollY=y;
  142.     getClientRect(&r);
  143.       invalidateRect(&r);
  144.     return;
  145.   }
  146.  
  147.   if (y>scrollY) { // tree scrolling up, scroller going down. invalidating from the bottom. bitblting from bottom to top
  148.     int lines = y-scrollY;
  149.     offset=-lines;
  150.     getClientRect(&r);
  151.     canvas = new WndCanvas();
  152.     canvas->attachToClient(this);
  153.  
  154.     Region *reg = new Region();
  155.     makeWindowOverlayMask(reg);
  156.     Region *clip = new Region(&r);
  157.     reg->offset(0, offset);
  158.     clip->subtract(reg);
  159.     canvas->selectClipRgn(clip);
  160.  
  161.     canvas->blit(r.left, r.top+lines, canvas, r.left, r.top, r.right-r.left, r.bottom-r.top-lines);
  162.  
  163.     canvas->selectClipRgn(NULL);
  164.       if (!reg->isEmpty())
  165.         invalidateRgn(reg);
  166.     delete clip;
  167.       delete reg;
  168.  
  169.     r.top = r.bottom-lines;
  170.   }
  171.   if (y<scrollY) { // tree scrolling down, scroller going up. invalidating from the top. bitblting from top to bottom
  172.     int lines = scrollY-y;
  173.     offset=lines;
  174.     getClientRect(&r);
  175.     canvas = new WndCanvas();
  176.     canvas->attachToClient(this);
  177.  
  178.     Region *reg = new Region();
  179.     makeWindowOverlayMask(reg);
  180.     Region *clip = new Region(&r);
  181.     reg->offset(0, offset);
  182.     clip->subtract(reg);
  183.     canvas->selectClipRgn(clip);
  184.  
  185.     canvas->blit(r.left, r.top, canvas, r.left, r.top+lines, r.right-r.left, r.bottom-r.top-lines);
  186.  
  187.     canvas->selectClipRgn(NULL);
  188.       if (!reg->isEmpty())
  189.         invalidateRgn(reg);
  190.     delete clip;
  191.       delete reg;
  192.  
  193.     r.bottom = r.top+lines+1;
  194.   }
  195.   if (canvas) {
  196.       delete canvas;
  197.       scrollY=y;
  198.  
  199.     // in case we have a virtualCanvas, we need to tell BaseWnd to call us to paint on it next time it's needed coz we blited directly to the screen
  200.     RECT cr;
  201.     getClientRect(&cr);
  202.     RECT screenblit;
  203.     SubtractRect(&screenblit, &cr, &r);
  204.     deferedInvalidateRect(&screenblit);
  205.  
  206.     // then invalidate what's needed
  207.       invalidateRect(&r);
  208.  
  209.       dbbuffer = 1;
  210.       repaint();
  211.   }
  212.  
  213.     if (signal) 
  214.       updateVScroll(y);
  215. }
  216.  
  217. // Scroll to a specified X-pixel
  218. void ScrlBkgWnd::scrollToX(int x, int signal) {
  219.   WndCanvas *canvas=NULL;
  220.   RECT r;
  221.   int offset;
  222.  
  223.   if (ABS(getRenderRatio() - 1.0) > 0.01) {
  224.       scrollX=x;
  225.     getClientRect(&r);
  226.       invalidateRect(&r);
  227.     return;
  228.   }
  229.  
  230.   if (x>scrollX) { // tree scrolling left, scroller going right. invalidating from the right. bitblting from right to left
  231.     int lines = x-scrollX;
  232.     offset=-lines;
  233.     getClientRect(&r);
  234.     r.top-=getHeaderHeight();
  235.     canvas = new WndCanvas();
  236.     canvas->attachToClient(this);
  237.  
  238.     Region *reg = new Region();
  239.     makeWindowOverlayMask(reg);
  240.     Region *clip = new Region(&r);
  241.     reg->offset(offset, 0);
  242.     clip->subtract(reg);
  243.     canvas->selectClipRgn(clip);
  244.  
  245.     canvas->blit(r.left+lines, r.top, canvas, r.left, r.top, r.right-r.left-lines, r.bottom-r.top);
  246.  
  247.     canvas->selectClipRgn(NULL);
  248.       if (!reg->isEmpty())
  249.         invalidateRgn(reg);
  250.     delete clip;
  251.       delete reg;
  252.  
  253.     r.left = r.right-lines-1;
  254.   }
  255.   if (x<scrollX) { // tree scrolling right, scroller going left. invalidating from the left. bitblting from left to right
  256.     int lines = scrollX-x;
  257.     offset=lines;
  258.     getClientRect(&r);
  259.     r.top-=getHeaderHeight();
  260.     canvas = new WndCanvas();
  261.     canvas->attachToClient(this);
  262.  
  263.     Region *reg = new Region();
  264.     makeWindowOverlayMask(reg);
  265.     Region *clip = new Region(&r);
  266.     reg->offset(offset, 0);
  267.     clip->subtract(reg);
  268.     canvas->selectClipRgn(clip);
  269.  
  270.     canvas->blit(r.left, r.top, canvas, r.left+lines, r.top, r.right-r.left-lines, r.bottom-r.top);
  271.  
  272.     canvas->selectClipRgn(NULL);
  273.       if (!reg->isEmpty())
  274.         invalidateRgn(reg);
  275.     delete clip;
  276.       delete reg;
  277.  
  278.     r.right = r.left+lines+1;
  279.   }
  280.   if (canvas) {
  281.       delete canvas;
  282.       scrollX=x;
  283.  
  284.     // in case we have a virtualCanvas, we need to tell BaseWnd to call us to paint on it next time it's needed coz we blited directly to the screen
  285.     RECT cr;
  286.     getClientRect(&cr);
  287.     cr.top-=getHeaderHeight();
  288.     RECT screenblit;
  289.     SubtractRect(&screenblit, &cr, &r);
  290.     deferedInvalidateRect(&screenblit);
  291.  
  292.     // then invalidate what's needed
  293.       invalidateRect(&r);
  294.  
  295.       dbbuffer = 1;
  296.       repaint();
  297.   }
  298.   
  299.   if (signal)
  300.     updateHScroll(x);
  301. }
  302.  
  303. void ScrlBkgWnd::setSlidersPosition() {
  304.  
  305.   if (!gethWnd()) return;
  306.  
  307.   RECT d;
  308.   getClientRect(&d);
  309.   if ((d.left >= d.right) || (d.top >= d.bottom))
  310.     return;
  311.  
  312.     RECT r;
  313.     if (inDestroy) return;
  314.     if (!isVisible()) {
  315.       needSetSliders=TRUE;
  316.       return;
  317.     }
  318.  
  319.   needSetSliders=FALSE;
  320.  
  321.     if (needHScroll()) {
  322.         getNonClientRect(&r);
  323.         r.top = r.bottom - getScrollbarWidth();
  324.         if (needVScroll())
  325.             r.right -= getScrollbarWidth() + (wantsep ? SCROLLBAR_SEP : 0);
  326.         RECT z; hScroll->getNonClientRect(&z);
  327.         if (!EqualRect(&r, &z)) {
  328.           hScroll->resizeToRect(&r);
  329.           RECT s=r;
  330.           s.bottom = s.top;
  331.           s.top -= (wantsep ? SCROLLBAR_SEP : 0);
  332.           hSep->resizeToRect(&s);
  333.         }
  334.         if (!hScroll->isVisible()) {
  335.           hScroll->setVisible(TRUE);
  336.           if (wantsep) hSep->setVisible(TRUE);
  337.           onHScrollToggle(TRUE);
  338.         }
  339.         hScroll->setNPages(((int)(getContentsWidth() / (r.right-r.left)))+1);
  340.         hScroll->setUpDownValue((int)(((float)lineHeight / (getContentsWidth()-(r.right-r.left)))*SCROLLBAR_FULL));
  341.         hScroll->setPosition((int)((float)scrollX / getMaxScrollX() * SCROLLBAR_FULL));
  342.     } else {
  343.         if (hScroll->isVisible()) {
  344.           hScroll->setVisible(FALSE);
  345.           if (wantsep) hSep->setVisible(FALSE);
  346.       onHScrollToggle(FALSE);
  347.         }
  348.         hScroll->setPosition(0);
  349.         scrollToX(0);
  350.     }
  351.  
  352.     if (needVScroll()) {
  353.         getNonClientRect(&r);
  354.         r.left = r.right - getScrollbarWidth();
  355.     if (needHScroll())
  356.       r.bottom -= getScrollbarWidth();
  357.         RECT z; vScroll->getNonClientRect(&z);
  358.         if (!EqualRect(&r, &z)) {
  359.           vScroll->resizeToRect(&r);
  360.           RECT s=r;
  361.           s.right = s.left;
  362.           s.left -= (wantsep ? SCROLLBAR_SEP : 0);
  363.           vSep->resizeToRect(&s);
  364.         }
  365.         if (!vScroll->isVisible()) {
  366.           vScroll->setVisible(TRUE);
  367.           if (wantsep) vSep->setVisible(TRUE);
  368.           onVScrollToggle(TRUE);
  369.         }
  370.         vScroll->setNPages(((int)(getContentsHeight() / (r.bottom-r.top)))+1);
  371.         vScroll->setUpDownValue((int)(((float)lineHeight / (getContentsHeight()-(r.bottom-r.top)))*SCROLLBAR_FULL));
  372.         vScroll->setPosition((int)((float)scrollY / getMaxScrollY() * SCROLLBAR_FULL));
  373.     } else {
  374.         if (vScroll->isVisible()) {
  375.           vScroll->setVisible(FALSE);
  376.           if (wantsep) vSep->setVisible(FALSE);
  377.           onVScrollToggle(FALSE);
  378.         }
  379.         vScroll->setPosition(0);
  380.         scrollToY(0);
  381.     }
  382.  
  383.   if (hSep) hSep->invalidate();
  384.   if (vSep) vSep->invalidate();
  385.  
  386.   if (needHScroll() && needVScroll()) {
  387.     getNonClientRect(&smsqr);
  388.     smsqr.left = smsqr.right - getScrollbarWidth();
  389.     smsqr.top = smsqr.bottom - getScrollbarWidth();
  390.     invalidateRect(&smsqr);
  391.   }
  392. }
  393.  
  394. void ScrlBkgWnd::onHScrollToggle(BOOL set) {
  395. }
  396.  
  397. void ScrlBkgWnd::onVScrollToggle(BOOL set) {
  398. }
  399.  
  400. int ScrlBkgWnd::onPaint(Canvas *canvas) {
  401.   RECT d;
  402.   getClientRect(&d);
  403.   if ((d.left >= d.right) || (d.top >= d.bottom)) {
  404.     return SCRLBKGWND_PARENT::onPaint(canvas);
  405.   }
  406.   
  407.   if (needSetSliders) setSlidersPosition();
  408.  
  409.   RECT z;
  410.   GetUpdateRect(gethWnd(), &z, FALSE);
  411.  
  412.   PaintCanvas paintcanvas;
  413.   PaintBltCanvas paintbcanvas;
  414.  
  415.   if (canvas == NULL) {
  416.     if (dbbuffer) {
  417.       if (!paintbcanvas.beginPaintNC(this)) return 0;
  418.       canvas = &paintbcanvas;
  419.     } else {
  420.       if (!paintcanvas.beginPaint(this)) return 0;
  421.       canvas = &paintcanvas;
  422.     }
  423.   }
  424.   dbbuffer=1;
  425.   SCRLBKGWND_PARENT::onPaint(canvas);
  426.  
  427.   Region *smsq = NULL;
  428.  
  429.   if (needHScroll() && needVScroll()) {
  430.     renderBaseTexture(canvas, smsqr);
  431.     smsq = new Region(&smsqr);
  432.   }
  433.  
  434.   RECT r;
  435.   getNonClientRect(&r);
  436.   RECT c={r.left,0,r.right,r.top}; // create label rect
  437.  
  438.   Region *reg = new Region(&c);
  439.   Region *clip = new Region();
  440.   if (canvas->getClipRgn(clip) == 0) { 
  441.     delete clip;
  442.     clip = new Region(&r);
  443.     if (smsq) clip->subtract(smsq);
  444.     canvas->selectClipRgn(clip);
  445.   } else {
  446.     clip->subtract(reg);
  447.     if (smsq) clip->subtract(smsq);
  448.     canvas->selectClipRgn(clip);
  449.   }
  450.   if (smsq) delete smsq;
  451.  
  452.   drawBackground(canvas);
  453.   delete clip;
  454.   delete reg;
  455.   if (getRenderRatio() != lastratio) { invalidate(); lastratio = getRenderRatio(); } // todo: make that an event
  456.   return 1;
  457. }
  458.  
  459. int ScrlBkgWnd::needDoubleBuffer() {
  460.   return dbbuffer;
  461. }
  462.  
  463. int ScrlBkgWnd::onEraseBkgnd(HDC dc) {
  464.  
  465. /*    DCCanvas canvas;
  466.     canvas.cloneDC(dc);
  467.  
  468.     drawBackground(&canvas);*/
  469.     
  470.     return 1;
  471. }
  472.  
  473. // Draws tiled background
  474. void ScrlBkgWnd::drawBackground(Canvas *canvas) {
  475.  
  476.     RECT r;
  477.     getClientRect(&r);
  478.   if (bmp.getBitmap() && bgColor == CLR_NONE) {
  479.       r.top-=scrollY%bmp.getBitmap()->getHeight();
  480.       r.left-=scrollX%bmp.getBitmap()->getWidth();
  481.       bmp.getBitmap()->blitTile(canvas, &r);
  482.   } else if (bgColor != CLR_NONE) {
  483.     canvas->fillRect(&r, bgColor);
  484.   }
  485. }
  486.  
  487. BOOL ScrlBkgWnd::needHScroll() {
  488.   if (!vScroll || !wantHScroll()) return FALSE;
  489.   RECT r;
  490.   getNonClientRect(&r);
  491.   if (vScroll->isVisible())
  492.     r.right -= getScrollbarWidth();
  493.   return (getContentsWidth() > r.right - r.left);
  494. }
  495.  
  496. BOOL ScrlBkgWnd::needVScroll() {
  497.   if (!hScroll || !wantVScroll()) return FALSE;
  498.   RECT r;
  499.   getNonClientRect(&r);
  500.   r.top += getHeaderHeight();
  501.   if (hScroll->isVisible())
  502.     r.bottom -= getScrollbarWidth();
  503.   return (getContentsHeight() > r.bottom - r.top);
  504. }
  505.  
  506. // Returns the current tree width in pixels
  507. int ScrlBkgWnd::getContentsWidth() {
  508.   /*RECT r;
  509.   ScrlBkgWnd::getClientRect(&r);
  510.   return r.right-r.left;*/
  511.   return 10000;
  512. }
  513.  
  514. // Returns the current tree height in pixels
  515. int ScrlBkgWnd::getContentsHeight() {
  516.   /*RECT r;
  517.   ScrlBkgWnd::getClientRect(&r);
  518.   return r.bottom-r.top;*/
  519.   return 10000;
  520. }
  521.  
  522. int ScrlBkgWnd::getMaxScrollY() {
  523.   RECT r;
  524.   getClientRect(&r);
  525.   return max(0, getContentsHeight()-(r.bottom-r.top));
  526. }
  527.  
  528. int ScrlBkgWnd::getMaxScrollX() {
  529.   RECT r;
  530.   getClientRect(&r);
  531.   return max(0, getContentsWidth()-(r.right-r.left));
  532. }
  533.  
  534. void ScrlBkgWnd::updateVScroll(int y) {
  535.     int z = (int)((float)y/getMaxScrollY()*SCROLLBAR_FULL);
  536.   vScroll->setPosition(z);
  537. }
  538.  
  539. void ScrlBkgWnd::updateHScroll(int x) {
  540.     int z = (int)((float)x/getMaxScrollX()*SCROLLBAR_FULL);
  541.     hScroll->setPosition(z);
  542. }
  543.  
  544. void ScrlBkgWnd::updateScrollY(int smooth) {
  545.   int y = (int)((float)(vScroll->getPosition())/SCROLLBAR_FULL * getMaxScrollY());
  546.   if (!smooth)
  547.     scrollToY(y /*& ~3*/);
  548.   else
  549.     smoothScrollToY(y);
  550. }
  551.  
  552. void ScrlBkgWnd::updateScrollX(int smooth) {
  553.     int x = (int)((float)(hScroll->getPosition())/SCROLLBAR_FULL * getMaxScrollX());
  554.   if (!smooth)
  555.       scrollToX(x /*& ~3*/);
  556.   else
  557.     smoothScrollToX(x);
  558. }
  559.  
  560. void ScrlBkgWnd::smoothScrollToX(int x) {
  561.   killSmoothXTimer();
  562.   smoothScrollXInc = -(float)(scrollX - x) / SMOOTH_STEPS;
  563.   smoothScrollXCur = (float)scrollX;
  564.   smoothScrollXTimerCount = 0;
  565.   smoothXTimer = 1;
  566.   setTimer(TIMER_SMOOTHSCROLLX, 25);
  567. }
  568.  
  569. void ScrlBkgWnd::killSmoothYTimer() {
  570.   if (smoothYTimer) {
  571.     killTimer(TIMER_SMOOTHSCROLLY);
  572.     smoothScrollYCur += smoothScrollYInc * (SMOOTH_STEPS - smoothScrollYTimerCount);
  573.     scrollToY((int)smoothScrollYCur);
  574.     smoothYTimer = 0;
  575.     updateVScroll(scrollY);
  576.   }
  577. }
  578.  
  579. void ScrlBkgWnd::killSmoothXTimer() {
  580.   if (smoothXTimer) {
  581.     killTimer(TIMER_SMOOTHSCROLLX);
  582.     smoothScrollXCur += smoothScrollXInc * (SMOOTH_STEPS - smoothScrollXTimerCount);
  583.     scrollToX((int)smoothScrollXCur);
  584.     smoothXTimer = 0;
  585.     updateHScroll(scrollX);
  586.   }
  587. }
  588.  
  589. void ScrlBkgWnd::smoothScrollToY(int y) {
  590.   killSmoothYTimer();
  591.   smoothScrollYInc = -(float)(scrollY - y) / SMOOTH_STEPS;
  592.   smoothScrollYCur = (float)scrollY;
  593.   smoothScrollYTimerCount = 0;
  594.   smoothYTimer = 1;
  595.   setTimer(TIMER_SMOOTHSCROLLY, 25);
  596. }
  597.  
  598. void ScrlBkgWnd::timerCallback (int id) {
  599.   switch (id) {
  600.     case TIMER_SMOOTHSCROLLY:
  601.       smoothScrollYCur += smoothScrollYInc;
  602.       scrollToY((int)smoothScrollYCur, FALSE);
  603.       if (++smoothScrollYTimerCount == SMOOTH_STEPS)
  604.         killSmoothYTimer();
  605.       return;
  606.     case TIMER_SMOOTHSCROLLX:
  607.       smoothScrollXCur += smoothScrollXInc;
  608.       scrollToX((int)smoothScrollXCur, FALSE);
  609.       if (++smoothScrollXTimerCount == SMOOTH_STEPS)
  610.         killSmoothXTimer();
  611.       return;
  612.   }
  613.   SCRLBKGWND_PARENT::timerCallback(id);
  614. }
  615.  
  616. // Gets notification from sliders
  617. int ScrlBkgWnd::childNotify(RootWnd *child, int msg, int param1, int param2) {
  618.   switch (msg) {
  619.     case UMSG_SCROLLBAR_SETPOSITION:
  620.         if (child == vScroll) {
  621.         updateScrollY(param1);
  622.         return 1;
  623.         }
  624.         if (child == hScroll) {
  625.           updateScrollX(param1);
  626.           return 1;
  627.         }
  628.         break;
  629.   }
  630.  
  631.   return SCRLBKGWND_PARENT::childNotify(child, msg, param1, param2);
  632. }
  633.  
  634. int ScrlBkgWnd::onResize() {
  635.   SCRLBKGWND_PARENT::onResize();
  636.   invalidateRect(&smsqr);
  637.   setSlidersPosition();
  638.   return 1;
  639. }
  640.  
  641. void ScrlBkgWnd::onSetVisible(int show) {
  642.   if (show)
  643.     setSlidersPosition();
  644. }
  645.  
  646. void ScrlBkgWnd::getClientRect(RECT *r) {
  647.   SCRLBKGWND_PARENT::getClientRect(r);
  648.   if (needVScroll())
  649.     r->right-=getScrollbarWidth()+(wantsep ? SCROLLBAR_SEP : 0);
  650.   if (needHScroll())
  651.     r->bottom-=getScrollbarWidth()+(wantsep ? SCROLLBAR_SEP : 0);
  652.   r->top += getHeaderHeight();
  653. }
  654.  
  655. void ScrlBkgWnd::getNonClientRect(RECT *r) {
  656.   SCRLBKGWND_PARENT::getClientRect(r); // my non client rect is my parent's client rect
  657.   return;
  658. }
  659.  
  660. int ScrlBkgWnd::getHeaderHeight() {
  661.   return 0;
  662. }
  663.  
  664. void ScrlBkgWnd::setLineHeight(int h) {
  665.   lineHeight = h;
  666. }
  667.  
  668. int ScrlBkgWnd::getLinesPerPage() {
  669.   RECT r;
  670.   getClientRect(&r);
  671.   int h = r.bottom - r.top;
  672.   return h / lineHeight;
  673. }
  674.  
  675. int ScrlBkgWnd::getScrollX() {
  676.   return scrollX;
  677. }
  678.  
  679. int ScrlBkgWnd::getScrollY() {
  680.   return scrollY;
  681. }
  682.  
  683. int ScrlBkgWnd::getScrollbarWidth() {
  684.   if (hScroll) return hScroll->getWidth();
  685.   if (vScroll) return vScroll->getWidth();
  686.   return 0;
  687. }
  688.  
  689. /*void ScrlBkgWnd::clientToScreen(RECT *r) {
  690.   POINT p;
  691.   p.x = r->left;
  692.   p.y = r->top;
  693.   SCRLBKGWND_PARENT::clientToScreen((int *)&p.x, (int*)&p.y);
  694.   r->left = p.x;
  695.   r->top = p.y;
  696.  
  697.   p.x = r->right;
  698.   p.y = r->bottom;
  699.   SCRLBKGWND_PARENT::clientToScreen((int *)&p.x, (int*)&p.y);
  700.   r->right = p.x;
  701.   r->bottom = p.y;
  702. }
  703.  
  704. void ScrlBkgWnd::clientToScreen(int *x, int *y) {
  705.   SCRLBKGWND_PARENT::clientToScreen(x, y);
  706. }
  707.  
  708. void ScrlBkgWnd::clientToScreen(POINT *p) {
  709.   TREEWND_PARENT::clientToScreen((int *)&p->x, (int *)&p->y);
  710. }*/
  711.  
  712. void ScrlBkgWnd::freeResources() {
  713.   SCRLBKGWND_PARENT::freeResources();
  714. }
  715.  
  716. void ScrlBkgWnd::reloadResources() {
  717.   SCRLBKGWND_PARENT::reloadResources();
  718. }
  719.  
  720. void ScrlBkgWnd::makeWindowOverlayMask(Region *r) {
  721.  
  722.   HDC dc = GetDC(gethWnd());
  723.  
  724.   if (getRandomRgn) {
  725.     RECT cr;
  726.     getClientRect(&cr);
  727.     RECT wr;
  728.     getWindowRect(&wr);
  729.  
  730.     Region *sr = new Region();
  731.     getRandomRgn(dc, sr->getHRGN(), SYSRGN);
  732.     sr->offset(-wr.left, -wr.top);
  733.  
  734.     r->setRect(&cr);
  735.     r->subtract(sr);
  736.     delete sr;
  737.   }
  738.   
  739.   ReleaseDC(gethWnd(), dc);  
  740. }
  741.